package br.com.ava.core.usuario;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;

import br.com.ava.core.infra.persistencia.ObjetoPersistente;

/**
 * Representa um Usuário no sistema.
 */
@Entity
@Table(name = "USUARIO")
@SequenceGenerator(name = Usuario.NOME_SEQ, sequenceName = Usuario.NOME_SEQ)
@SuppressWarnings("serial")
public class Usuario extends ObjetoPersistente implements UserDetails {

	protected static final String NOME_SEQ = "SEQ_USUARIO";

	private String nome;
	private String login;
	private String senha;
	private PerfilEnum perfil;

	/** {@inheritDoc} */
	@Id
	@Column(name = "id", nullable = false)
	@GeneratedValue(strategy = GenerationType.AUTO, generator = Usuario.NOME_SEQ)
	@Override
	public Integer getId() {
		return id;
	}

	@NotNull
	@Size(min = 1, max = 1020)
	@Column(name = "nome", nullable = false)
	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	@NotNull
	@Size(min = 1, max = 50)
	@Column(name = "login", nullable = false)
	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	@NotNull
	@Size(min = 1, max = 1000)
	@Column(name = "senha", nullable = false)
	public String getSenha() {
		return senha;
	}

	public void setSenha(String senha) {
		this.senha = senha;
	}

	@Transient
	public PerfilEnum getPerfil() {
		return perfil;
	}

	public void setPerfil(PerfilEnum perfil) {
		this.perfil = perfil;
	}

	@Override
	public boolean equals(Object obj) {
		boolean iguais = false;
		if (obj == this) {
			iguais = true;
		} else if (obj instanceof Usuario) {
			Usuario objeto = (Usuario) obj;
			iguais = new EqualsBuilder().append(nome, objeto.nome)
					.append(login, objeto.login).append(senha, objeto.senha)
					.isEquals();
		}
		return iguais;
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(nome).append(login).append(senha)
				.toHashCode();
	}

	@Override
	public String toString() {
		return nome;
	}

	/** {@inheritDoc} */
	@Override
	@Transient
	@SuppressWarnings("deprecation")
	public Collection<? extends GrantedAuthority> getAuthorities() {
		List<GrantedAuthority> retorno = new ArrayList<GrantedAuthority>();

		if (perfil != null) {
			retorno.add(new GrantedAuthorityImpl(perfil.getDescricao()));
		}
		return retorno;
	}

	/** {@inheritDoc} */
	@Override
	@Transient
	public String getPassword() {
		return getSenha();
	}

	/** {@inheritDoc} */
	@Override
	@Transient
	public String getUsername() {
		return getLogin();
	}

	/** {@inheritDoc} */
	@Override
	@Transient
	public boolean isAccountNonExpired() {
		return true;
	}

	/** {@inheritDoc} */
	@Override
	@Transient
	public boolean isAccountNonLocked() {
		return true;
	}

	/** {@inheritDoc} */
	@Override
	@Transient
	public boolean isCredentialsNonExpired() {
		return true;
	}

	/** {@inheritDoc} */
	@Override
	@Transient
	public boolean isEnabled() {
		return true;
	}
}
